﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SmartSpace.Core;

namespace SmartSpace.Cwt
{
    public class CwtService : ICwtService
    {
        private ICwtFactory _cwtFactory;

        private ICoreFactory _coreFactory;

        public CwtService(ICoreFactory coreFactory, ICwtFactory cwtFactory)
        {
            _coreFactory = coreFactory;
            _cwtFactory = cwtFactory;
        }

        public Company GetCompany()
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<Company>().FirstOrDefault();
            }
        }

        public bool SaveCompany(Company company)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Company>().Where(p => p.Id == company.Id)
                    .Select(p => p.Id).FirstOrDefault() != default(Guid))
                {
                    // update
                    context.Entry(company).State = System.Data.EntityState.Modified;
                }
                else if (context.Set<Company>().FirstOrDefault() == null)
                {
                    // insert
                    context.Set<Company>().Add(company);
                }
                else
                {
                    // error
                    return false;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public bool SaveSummary(Summary summary)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Summary>()
                     .Where(p => p.Id == summary.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<Summary>().Add(summary);
                }
                else
                {
                    context.Entry(summary).State = System.Data.EntityState.Modified;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool DeleteSummary(Summary summary)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Summary>()
                     .Where(p => p.Id == summary.Id)
                     .Select(p => p.Id).FirstOrDefault() != default(Guid))
                {
                    context.Entry(summary).State = System.Data.EntityState.Deleted;
                }
                else
                {
                    return false;
                }
                context.SaveChanges();
                return true;
            }
        }

        public Summary FindSummary(Guid id)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<Summary>()
                    .Where(p => p.Id == id).SingleOrDefault();
            }
        }

        public List<Summary> FindSummaries()
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<Summary>()
                    .OrderBy(p => p.Order)
                    .ToList();
            }
        }

        public bool SaveCategory(Category category)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Category>()
                     .Where(p => p.Id == category.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<Category>().Add(category);
                }
                else
                {
                    context.Entry(category).State = System.Data.EntityState.Modified;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool DeleteCategory(Category category)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Category>()
                     .Where(p => p.Id == category.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<Category>().Remove(category);
                }
                else
                {
                    context.Entry(category).State = System.Data.EntityState.Deleted;
                }
                context.SaveChanges();
                return true;
            }
        }

        public Category FindCategory(string code)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<Category>().Where(p => p.Code == code).FirstOrDefault();
            }
        }

        public List<Category> FindCategories()
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<Category>().ToList();
            }
        }

        public bool SaveArticle(Article article)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Article>()
                     .Where(p => p.Id == article.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<Article>().Add(article);
                }
                else
                {
                    context.Entry(article).State = System.Data.EntityState.Modified;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool DeleteArticle(Article article)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Article>()
                     .Where(p => p.Id == article.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<Article>().Remove(article);
                }
                else
                {
                    context.Entry(article).State = System.Data.EntityState.Deleted;
                }
                context.SaveChanges();
                return true;
            }
        }

        public Article FindArticle(Guid id)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<Article>()
                    .Include("Category")
                    .Where(p => p.Id == id).SingleOrDefault();
            }
        }

        public PagedList<Article> FindArticles(Guid categoryId, int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Article> pagedList = new PagedList<Article>();
                pagedList.AddRange(context.Set<Article>()
                    .Where(p => p.CategoryId == categoryId)
                    .OrderBy(p => p.PostedDate)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Article>()
                    .Where(p => p.CategoryId == categoryId)
                    .OrderBy(p => p.PostedDate).Count();
                return pagedList;
            }
        }

        public PagedList<Article> FindArticles(string categoryCode, int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Article> pagedList = new PagedList<Article>();
                pagedList.AddRange(context.Set<Article>()
                    .Where(p => p.Category.Code == categoryCode)
                    .OrderBy(p => p.PostedDate)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Article>()
                    .Where(p => p.Category.Code == categoryCode)
                    .OrderBy(p => p.PostedDate).Count();
                return pagedList;
            }
        }

        public PagedList<Article> FindHotArticles(Guid categoryId, int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Article> pagedList = new PagedList<Article>();
                pagedList.AddRange(context.Set<Article>()
                    .Where(p => p.CategoryId == categoryId)
                    .OrderBy(p => p.VisitPoint)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Article>()
                    .Where(p => p.CategoryId == categoryId)
                    .Count();
                return pagedList;
            }
        }

        public PagedList<Article> FindHotArticles(int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Article> pagedList = new PagedList<Article>();
                pagedList.AddRange(context.Set<Article>()
                    .OrderBy(p => p.VisitPoint)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Article>()
                    .Count();
                return pagedList;
            }
        }

        public PagedList<Article> FindTopArticles(Guid categoryId, int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Article> pagedList = new PagedList<Article>();
                pagedList.AddRange(context.Set<Article>()
                    .Where(p => p.CategoryId == categoryId)
                    .OrderBy(p => p.TopPoint)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Article>()
                    .Where(p => p.CategoryId == categoryId)
                    .Count();
                return pagedList;
            }
        }

        public PagedList<Article> FindTopArticles(int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Article> pagedList = new PagedList<Article>();
                pagedList.AddRange(context.Set<Article>()
                    .OrderBy(p => p.TopPoint)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Article>()
                    .Count();
                return pagedList;
            }
        }

        public bool SavePartnerLink(PartnerLink link)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<PartnerLink>()
                     .Where(p => p.Id == link.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<PartnerLink>().Add(link);
                }
                else
                {
                    context.Entry(link).State = System.Data.EntityState.Modified;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool DeletePartnerLink(PartnerLink link)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<PartnerLink>()
                     .Where(p => p.Id == link.Id)
                     .Select(p => p.Id).FirstOrDefault() != default(Guid))
                {
                    context.Entry(link).State = System.Data.EntityState.Deleted;
                }
                else
                {
                    return false;
                }
                context.SaveChanges();
                return true;
            }
        }

        public PartnerLink FindPartnerLink(Guid id)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<PartnerLink>().Where(p => p.Id == id).SingleOrDefault();
            }
        }

        public List<PartnerLink> FindPartnerLinks()
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                return context.Set<PartnerLink>()
                    .OrderBy(p => p.Order).ToList();
            }
        }

        public bool SaveContact(Contact contact)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Contact>()
                     .Where(p => p.Id == contact.Id)
                     .Select(p => p.Id).FirstOrDefault() == default(Guid))
                {
                    context.Set<Contact>().Add(contact);
                }
                else
                {
                    context.Entry(contact).State = System.Data.EntityState.Modified;
                }
                context.SaveChanges();
                return true;
            }
        }

        public bool DeleteContact(Contact contact)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                if (context.Set<Contact>()
                     .Where(p => p.Id == contact.Id)
                     .Select(p => p.Id).FirstOrDefault() != default(Guid))
                {
                    context.Entry(contact).State = System.Data.EntityState.Deleted;
                }
                else
                {
                    return false;
                }
                context.SaveChanges();
                return true;
            }
        }

        public PagedList<Contact> FindContacts(string filter, int start, int limit)
        {
            using (CwtContext context = _cwtFactory.Get())
            {
                PagedList<Contact> pagedList = new PagedList<Contact>();
                pagedList.AddRange(context.Set<Contact>()
                    .Where(p=>p.Name.Contains(filter) || p.Email.Contains(filter))
                    .OrderBy(p => p.SubmitDate)
                    .Skip(start)
                    .Take(limit)
                    .ToList());
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<Contact>()
                    .Where(p => p.Name.Contains(filter) || p.Email.Contains(filter))
                    .Count();
                return pagedList;
            }
        }
    }
}
